import sys
sys.path.append('src/python')
import optparse
import os
import math
from itertools import groupby

def chomp(line):
    if line == None:
        return None
    if line[-1] == '\n':
        line = line[:-1]
    if line[-1] == '\r':
	    line = line[:-1]
    return line

def count_iter(iterator):
    count = 0
    for i in iterator: count += 1
    return count

if __name__ == '__main__':
    parser = optparse.OptionParser()
    parser.add_option('-i','--input-directory',dest='input_directory',
        help='extraction result input directory')

    parser.add_option('-o','--output-directory',dest='output_directory',
        help='output direcotry',default='.')

    options,args = parser.parse_args()

    if not os.path.exists(options.input_directory) or \
        not os.path.exists(options.output_directory):
        print 'invalid arguments,please check and retry'

    try:
        metrics_handle = open(os.path.join(options.input_directory, 'metrics.dat'))
        entity_handle = open(os.path.join(options.input_directory,'entity.dat'))
        link_handle = open(os.path.join(options.input_directory,'link.dat'))
        structure_handle = open(os.path.join(options.input_directory,'structure.dat'))
        entity_map = {}

        metrics = dict([(y[0],float(y[1])) for y in \
            [x.split('=') for x in chomp(metrics_handle.readline()).split(';')]])
        print metrics
        entities = map(lambda x:(long(x[0]),x[1],x[2]),\
            [chomp(i).split(',') for i in iter(entity_handle)])
        for entity in entities: entity_map[entity[1]] = entity;print entity[1]
        links = map(lambda x:(long(x[0]),long(x[1]),long(x[2]),x[3]), \
            [chomp(i).split(',') for i in iter(link_handle)])

        structures = map(lambda x: (x[1],entity_map[x[2]][0]),\
            [chomp(i).split(',') for i in iter(structure_handle)])
    finally:
        try:
            metrics_handle.close()
            link_handle.close()
            entity_handle.close()
        except:
            pass

    factors = {'extend relation':(1.0,1.0),
        'implement relation':(metrics['ANMPC']/(metrics['ANMPC'] + metrics['ANVPC']),1.0),
        'simple association':(1.0/metrics['ANVPC'],1-(metrics['ANVCIPC']/metrics['ANVPC'])),
        'head dependancy relation':((1.0/(metrics['ANVPC']) / metrics['ANMPC']),\
            1-metrics['ANMHDPC']/metrics['ANMPC']),
        'body dependancy relation':(((1.0/(metrics['ANVPC']) / metrics['ANMPC'])/metrics['ANSPM']),\
            1-metrics['ANMBDPC']/metrics['ANMPC'])
    }
    print str(factors)

    matrix = map(lambda x: map(lambda y: 0.0,xrange(len(entities))),\
        xrange(len(entities)))
    def link_sort(x,y):
        anchorx = ','.join([str(x[1]),str(x[2])])
        anchory = ','.join([str(y[1]),str(y[2])])
        if anchorx == anchory:
            return cmp(x[3],y[3])
        return cmp(anchorx,anchory)

    def weight(c,w,df):
        sum = 0.0
        for i in range(c): sum += math.pow(df, i) * w
        return sum

    links.sort(cmp=link_sort)
    for k, g in groupby(links,lambda x:','.join([str(x[1]),str(x[2])])):
        start,end = tuple(map(lambda x: long(x),k.split(',')))
        w = 0.0
        for link_type, iterator in groupby(list(g),lambda x: x[3]):
            w += weight(count_iter(iterator),factors[link_type][0],factors[link_type][1])
        matrix[start][end] = w

    try:
        graph_output_handle = open(os.path.join(options.output_directory,'graph_sample.txt'),'w')
        graph_output_handle.write('%d\n' % (len(entities)))
        graph_output_handle.write(' '.join([str(x[0]) for x in entities]) + '\n')
        for i in range(len(matrix)):
            graph_output_handle.write(' '.join(map(lambda x: str(x),matrix[i])) + '\n')
    finally:
        try:
            graph_output_handle.close()
        except:
            pass

    graph = {}
    packages = set()
    for package in map(lambda x: x[0],structures):
        packages.add(package)
    for package in packages:
        graph[package] = ([],[])

    relations = []
    packages = list(packages)
    packages.sort()
    packages.reverse()
    print str(packages)
    stack = []
    for i, v in enumerate(packages):
        if len(stack) == 0:
            stack.append(v)
        else:
            if stack[-1].startswith(v):
                r = map(lambda x:(v,x),\
                    [x for x in stack if x.startswith(v)])
                del stack[(len(stack)-len(r)):]
                relations += r
            stack.append(v)

    if len(stack) > 0:
        relations += map(lambda x:('root',x),stack)
    graph['root'] = ([],[])

    for relation in relations:
        print relation
        start = relation[0]
        end = relation[1]
        graph[start][0].append(end)

    for structure in structures:
        graph[structure[0]][1].append(structure[1])

    def traverse(node):
        buffer = []
        buffer.append('(')
        temp = []
        for child in graph[node][0]:
            temp.append(traverse(child))
        for atomic in graph[node][1]:
            temp.append(str(atomic))
        buffer.append('-'.join(temp))
        buffer.append(')')
        return ''.join(buffer)

    try:
        structure_output_handle = open(os.path.join(options.output_directory,'structure_sample.txt'),'w')
        structure_output_handle.write(traverse('root')+'\n')
    finally:
        try:
            structure_output_handle.close()
        except:
            pass
